/**
 * @file RSVideoCapture.h
 * @author 覃雨涛 (1264145445@qq.com)
 * @brief intel realsense深度相机驱动头文件
 * @version 1.0
 * @date 2022-01-22
 *
 * @copyright Copyright SCUT RobotLab(c) 2022
 *
 */

#pragma once

#include <opencv2/videoio.hpp>
#include <librealsense2/hpp/rs_pipeline.hpp>
#include <librealsense2/hpp/rs_record_playback.hpp>
#include <librealsense2/hpp/rs_sensor.hpp>
#include "Logging.h"

#define REALSENSE_CAPTURE 0
#define BAGFILE_CAPTURE 1
#define OPENCV_CAPTURE 2
#define VIDEO_CAPTURE 3

class RSVideoCapture : public cv::VideoCapture
{
private:
    // ------------------ rs库对象 ---------------------
    rs2::context __cxt;                                // realsense装置环境
    std::shared_ptr<rs2::align> __align;               // realsense对齐
    rs2::config __config;                              // realsense配置
    rs2::pipeline_profile __profile;                   // realsense管道配置
    std::shared_ptr<rs2::pipeline> __pipe;             // realsense管道
    rs2::device __device;                              // realsense设备
    rs2::hole_filling_filter __hole_filling_filter;    // 深度图空洞过滤器
    cv::VideoCapture* cap = nullptr;
    // ------------------ 标志位 -----------------------
    int __capture_status;                // Capture状态
    std::string __path;                  // 视频文件路径
    uint8_t __serial_num;                // video串口号
    bool __is_inited = false;            // 初始化标志位
    bool __is_config_set = false;        // 配置标志位
    bool __is_pipeline_start = false;    // 管道流标志位
    // ------------------ 相机参数 ---------------------
    int width = 848;        // 图像宽度
    int height = 480;       // 图像高度
    float exposure;         // 曝光
    float gain;             // 增益
    float gamma;            // Gamma
    float contrast;         // 对比度
    float brightness;       // 亮度
    float white_balance;    // 白平衡

    // --------------- 数据流、帧集变量 ----------------
    rs2::frameset __frames;    // 存储彩色图像帧和深度图像帧

    using VideoCapture::open;    // 禁止外部使用VideoCapture的open方法

public:
    // 构造
    RSVideoCapture();
    // 模组相机构造
    RSVideoCapture(uint8_t);
    // 文件构造
    RSVideoCapture(const std::string&);
    // 析构
    virtual ~RSVideoCapture() override;
    // 打开相机
    bool open();
    // 设置相机参数
    virtual bool set(int propId, double value) override;
    // 读取
    bool read(cv::Mat&, cv::Mat&);
    // 读取状态
    bool isOpened()
    {
        return this->grab();
    };
    // 打开bag录制
    void BagWrite();

private:
    // 抓取最新帧并返回状态
    bool grab()
    {
        return __pipe->try_wait_for_frames(&__frames, 800U);
    };
    // 重连
    bool reconnect();
};
